JavaScript
JavaScript
  循环与迭代
    while｜do...while
    for
    for...of
      for...of语句在可迭代对象（包括 Array，Map，Set，String，TypedArray，arguments 对象等等）上创建一个迭代循环，调用自定义迭代钩子，并为每个不同属性的值执行语句
    for...in
      for...in 语句以「任意顺序」迭代一个对象的除Symbol以外的可枚举属性，包括继承的可枚举属性
  Set&WeakSet
    保存唯一值和插入顺序。Set 可以保存任何值，WeakSet只能保存对象的弱引用
    size
      成员数量
      Set独有
    方法
      clear()
        清除所有元素
      entries()
        按插入顺序返回[value, value]迭代器
      forEach(callback)
        按插入顺序并对元素逐一执行callback
      keys/values()
        按插入顺序返回元素值的迭代器
      add(value)
        如果没有具有相同值的元素，则插入指定值的新元素
      delete(value)
        删除指定元素，元素不存在则返回false，否则返回true
      has(value)
        判断指定值是否存在
      Set独有
      共有方法
  继承和原型链
    JavaScript 只有一种结构：对象。每个实例对象（object）都有一个私有属性（称之为 __proto__）指向它的构造函数的原型对象（prototype）。该原型对象也有一个自己的原型对象（__proto__），层层向上直到一个对象的原型对象为 null。根据定义，null 没有原型，并作为这个原型链中的最后一个环节
    Object.hasOwnProerty() 和 Object.keys() 可以枚举属性而不遍历原型链
    创造对象的几个方法
      语法结构
        var o = {a: 1};
        var a = ["yo", "whadup", "?"];
        function f(){ return 2; }
      构造器
        new
      Object.create(prototype)
      class 关键字
  Map&WeakMap
    保存键值对和键的插入顺序。Map任何值都可以作为键；WeakMap只能以对象作为键，且为弱引用
      Map通过两个数组分别存放键/值来实现保持顺序
    size
      成员数量
    方法
      clear()
        清除所有键值对
      entries()
        按插入顺序返回键值对[]迭代器
      keys/values()
        按插入顺序返回键/值的迭代器
      forEach(callback)
        按插入顺序并对元素逐一执行callback
      delete(key)
        删除指定元素，元素不存在则返回false，否则返回true
      get(key)
        获取指定键的值
      set(key, value)
        添加或修改键值对
      has(key)
        判断指定键值对是否存在
      共有方法
      Map独有方法
  Generator
    定义
      function* gen() {
yield 1;
yield 2;
}
const g = gen()
    方法
      next()
        返回value和done
      return(value?)
        返回指定的值或undefined，并将生成器的done标志为true
  变量
    var
    es6｜块级作用域
      let
      const
  运算符
    +
      连接字符串
      隐含转换
        "3" + 4 + 5; // 345
        3 + 4 + "5"; // 75
    相等运算符
      ==/!=
        123 == "123" // true
        1 == true; // true
      ===/!==
        1 === true; //false
        123 === "123"; // false
    && and ||
      短路逻辑（short-circuit logic），是否会执行第二个语句（操作数）取决于第一个操作数的结果
      提前校验
        var name = o && o.getName();
      缓存｜默认值
        var name = cachedName || getName() || defaultName;
        注意末尾不能是或可能是 false 类的值
    new
      new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例
      执行过程
        1. 创建一个空的简单 JavaScript 对象（即 {}）；
2. 为步骤 1 新创建的对象添加属性 __proto__，将该属性链接至构造函数的原型对象；
3. 将步骤 1 新创建的对象作为 this 的上下文；
4. 如果该函数没有返回对象，则返回 this
  异步
    Promise
      Promise 对象用于表示一个一步操作的最终完成（或失败）及其结果值
      Promise状态
        待定/pending
        已敲定/settled
          已兑现/fulfilled
          已拒绝/rejected
      方法
        Promise.all(iterable)
          返回全部 promise 的 resolved 或者第一个 rejected
        Promise.any(iterable)
          返回第一个resolved的或者全部reject时返回rejection
        Promise.race(iterable)
          返回第一个敲定的结果
        链式调用
          then
          catch
          finally
    async
    await
      等待一个Promise实现，只能在异步函数或模块顶层
  版本
    ES5/2009
    ES6/2015
    ES 2016
  模块
    require
      对象写法，通过闭包/立即执行函数写法实现不暴露私有成员的目的
      运行时动态加载
      规范
        CommonJS
          module.exports/ exports
          全局 require(module) 方法
        AMD/CMD
          因为前端有异步加载的需求而出现
          define(['lib'], function(lib){return mod})
          require([module], callback)
    es6 modules
      export
      import
      编译时加载，不支持变量、表达式
  基本类型
    String
      Unicode-16 编码
    Number
      遵循 IEEE754标准64位双精度浮点数格式
      具体实现时，整数值通常被视为 32 位整型变量进行操作和存储（个别浏览器），为了方便位操作
    Bigint
    Boolean
      false、0、空字符串（""）、NaN、null 和 undefined 被转换为 false
        这里要注意关于数值范围的判断，最好手动加判定范围
      所有其他值被转换为 true
    Symbol
    Null
      只有一个值 null
      typeof 返回 object
    Undefined
  全局属性
    NaN（No-a-Number）
      isNaN
    Infinity
      isFinite
    undefined
  Object
    数据属性
      value
      writable
      enumerable
      configurable
    访问器属性
      get
      set
      enumerable
      configurable
    创建和构造
      Object 构造函数为给定的参数创建一个包装类对象（object wrapper），具体有以下情况：
        如果给定值是 null 或 undefined，将会创建并返回一个空对象
        如果传进去的是一个基本类型的值，则会构造其包装类型的对象
        如果传进去的是引用类型的值，仍然会返回这个值，经他们复制的变量保有和源对象相同的引用地址
      当以非构造函数形式被调用时，Object 的行为等同于 new Object()
    深浅拷贝
      浅拷贝是创建一个新的对象，有原始对象属性值的精确拷贝，如果是属性是引用类型则拷贝内存地址，两个对象共享部分内存空间，修改会互相影响
      深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象
      深拷贝的实现
        JSON.parse(JSON.stringify())
        JQuery.extend(deepClone = true, target, source, [sources])
        实现思路
          递归遍历对象，复制基本类型，遇到 typeof === ‘object’ 的情况，先在hash里找到是否已经存在，没有的话通过原型链上的 constructor 创建新的空白对象，枚举属性并递归拷贝值
    方法
      Object.assign(target, ...sources)
        将源中可枚举的自有属性浅拷贝/覆盖到目标
      Object.create(proto)
        使用现有的对象作为原型创建一个新的对象
      Object.keys(obj)
        返回一个由一个给定对象的自身可枚举属性组成的数组，数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致
      Object.values(obj)
        返回一个给定对象自身的所有可枚举属性值的数组
      Object.defineProperties(obj, props)
        直接在一个对象上修改现有属性或定义新属性，返回该对象
      Object.entries(obj)
        返回一个给定对象自身可枚举属性的键值对数组
      Object.fromEntries(iterable);
        把键值对列表转换为一个对象
      Object.freeze(obj)
        冻结一个对象及其属性和原型
        存在深浅冻结的问题
      Object.isFrozen(obj)
        判断一个对象是否冻结
      Object.hasOwn(instance, prop)
        判断一个对象是否自有属性
  Function
    属性
      length
        形式参数个数
      name
        函数实例名称
      prototype
        原型，当函数作为构造函数时，prototype将作为新对象的原型
    方法
      apply(thisArg, argsArray?)
      bind(thisArg[, arg...])
      call(thisArg, arg...)
      总结
        apply 、 call 、bind 三者都是用来改变函数的this对象的指向的；
        apply 、 call 、bind 三者第一个参数都是this要指向的对象，也就是想指定的上下文；
        apply 、 call 、bind 三者都可以利用后续参数传参；
        bind 是返回对应函数，便于稍后调用；apply 、call 则是立即调用 。
    闭包
      闭包（closure）是一个函数以及其捆绑的周边环境状态（lexical environment，词法环境）的引用的组合。换而言之，闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中，闭包会随着函数的创建而被同时创建
      应用
        func(argument) return func
        避免var带来的一些问题
        柯里化
          柯里化（Currying）是一种函数式编程技术，它将一个接受多个参数的函数转换为一系列只接受单个参数的函数。例如，将一个接受两个参数的函数转换为一系列接受一个参数的函数。
柯里化的核心思想是，将一个多参数函数的调用转换为一系列单参数函数的调用，使得这些函数更加通用和灵活，并且可以方便地组合和复用。
  Array
    Array 是一种对象，以非负整数为下标（会隐私转换为字符串），只能通过方括号表示法进行访问
    length 实际是最大合法索引值+1，通过修改length可以删除元素或填充空元素
    方法
      查找与访问
        at(index)
          访问对应下标元素，负数表示倒数
        find/findLast(callback)
          返回通过callback找到的第一个/最后一个元素，不存在则返回undefined
        findIndex/findLastIndex(callback)
          返回通过callback找到的第一个/最后一个元素的下标，不存在则返回-1
        includes(target, fromIndex?)
          判断是否包含指定值
        indexOf/lastIndexOf(target, fromIndex?)
          返回数组中目标元素的第一个/最后一个索引，不存在则返回-1
        fromIndex用于指定搜索范围，可为负数，小于-length则全部搜索
      直接操作
        shift/pop()
          删除第一个/最后一个元素，并返回该元素值
        unshift/push(...elements)
          在数组开头/末尾插入给定的值，并返回数组新的长度
        copyWithin(target, start?, end?)
          复制指定片段到指定位置
        fill(value, start?, end?)
          用指定值填充指定片段
        sort(compareFn=(a,b)=>b.toString()-a.toString())
          原地算法对数组排序，并返回数组。默认排序顺序是在将元素转换为字符串，然后比较它们的UTF-16码。返回值应为数字，升序排序。
        splice(start, deleteCount?, ...items?)
          通过删除或替换或原地添加新元素的方法来修改原数组，并返回被修改的内容
        reverse()
          反转数组并返回其引用
      判断
        Array.isArray(value)
          判断传入值是否为数组
        every(callback)
          测试一个数组内的所有元素是否都能通过指定函数的测试。空数组永远返回true
        some(callback)
          测试一个数组内是否至少一个元素能通过callback测试。空数组永远返回fase
      转化
        Arrar.from(arrayLike, mapFn)
          返回一个类数组/可迭代对象的浅拷贝数组，等于from(arrayLike).map(mapFn)
        concat(...arrays/...values)
          合并数组
        entries()
          返回一个新的数组迭代器对象，该对象包含数组中每个索引的键/值对，空值为undefined
        keys()
          返回包含数组中每个索引键的Array Iterator对象
        values()
          返回包含数组中每个值的Array Iterator对象
        filter(callback)
          通过指定方法过滤数组并返回其浅拷贝
        flat(depth=1)
          根据指定深度展平数组，过滤空项后合并返回新数组。depth=Infinity 则完全展平
        flatMap(callback)
          等同于Array.map(callback).flat()
        forEach(callback)
          遍历数组元素并对其执行callback
        map(callback)
          遍历数组元素并对其执行callback，并返回其结果数组
        reduce/reduceRight(perviousValue=initialValue/array[0], currentValue=initialValue? array[0]:array[1], currentIndex=initialValue? 0:1, array)
          按从左到右/从右到左的顺序执行累运行callback并返回最终结果
        slice(start?, end?)
          返回数组的浅拷贝切片
        join(separator=‘,’)
          将数组所有元素通过指定分隔符连接成一个字符串，隐式调用toString
  String
    全局对象，用于字符串或字符序列的构造函数
    常用方法
      类似Array的方法
        at(index)
        concat(str, [...str])
        includes(str, fromIndex)
        indexOf/lastIndexOf(str, fromIndex)
        slice(beginIndex, endIndex)
      startWith/endsWith(searchString, length = str.length)
        判断当前字符串是否以给定字符串开头/结尾
      match(regexp)
        返回字符串进行正则匹配的结果
      matchAll(regexp)
        返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器
      padStart/padEnd(targetLength, padString=' ')
        在字符串开头/结尾填充指定字符串（默认为一个空格，可重复填充）到目标长度。目标长度小于等于当前长度则直接返回
      repeat(count)
        返回一个原来字符串重复count次的字符串
      replace(regexp|substr, newSubstr|function)
        用新的字符串/函数返回值替换正则匹配到的所有子串或者第一个字面匹配子串，返回新的字符串
      replaceAll(regexp|substr, newSubstr|function)
        和replace类似，返回替换全部匹配项后的字符串
      search(regexp)
        匹配正则表达式，返回的首次匹配的下标，否则返回-1
      split(separator[, limit])
        用指定分隔符分割字符串并返回限制元素数量的数组（无限制则返回全部）
          反转字符串还是array比较好
      substring(indesStart[, indexEnd])
        类似array.slice，返回字符串切片
      toLocaleLowerCase/toLocalUpperCase(locale?)
        根据传入的地区或者本地地区进行小写/大写字母转换
      toLowerCase/toUpperCase()
        将字符串转换为小写/大写
      trim/trimStart(trimLeft)/trimEnd(trimRight)()
        清除字符串两端/左侧/右侧空格
在 JavaScript 中，基本类型（基本数值、基本数据类型）是一种既非对象也无方法或属性的数据